#include <iostream>
#include <vector>
#include "pcapio.h"
#include <pcap.h>
using namespace std;

int main()
{
	std::map<std::string,std::string > devmap;
	std::vector<std::string> names;
	std::string errstring = PCAPIO::pcapio_interfaces(devmap);
	if (errstring.size())
	{
		cout <<"Error:\n"<<errstring<<"\n";
		return 0;
	}
	for (auto & p : devmap)
	{
		names.push_back(p.first);
		cout <<"==========\n";
		cout << "Device " << names.size() <<":\n";
		cout <<p.second;
	}

	cout <<"Input src device id 1~"<<names.size()<<":";
	unsigned int nID = 0;
	cin >> nID;
	if (!nID || nID > devmap.size())
	{
		cout <<"Invalid ID out of range\n";
		return 0;
	}
	std::string strDev = names[nID-1];

	pcap_t *handle = NULL;
	char errbuf[PCAP_ERRBUF_SIZE];
	//handle = pcap_open_live(strDev.c_str(), 65535, 1, 10, errbuf);
	handle = pcap_create(strDev.c_str(), errbuf);
	if(handle == NULL)
	{
		printf("pcap_open_live return err,errbuf:%s...\n", errbuf);
		return -1;
	}
	if (pcap_set_buffer_size(handle, 128 * 1024 * 1024) != 0)
	{
		printf("pcap_open_live return err,errbuf:%s...\n", pcap_geterr(handle));
		//pcap_close(handle);
		//break;
	}
	if (pcap_set_promisc(handle, 1) != 0)
	{
		printf("pcap_open_live return err,errbuf:%s...\n", pcap_geterr(handle));
		//pcap_close(handle);
		//break;
	}
	if (pcap_set_snaplen(handle, 65536) != 0)
	{
		printf("pcap_open_live return err,errbuf:%s...\n", pcap_geterr(handle));
		//pcap_close(handle);
		//break;
	}
	if (pcap_set_timeout(handle, 1000) != 0)
	{
		printf("pcap_open_live return err,errbuf:%s...\n", pcap_geterr(handle));
		//pcap_close(handle);
		//break;
	}
	if (pcap_activate(handle) != 0)
	{
		printf("pcap_open_live return err,errbuf:%s...\n", pcap_geterr(handle));
		pcap_close(handle);
		return -1;
	}
	if (pcap_datalink(handle)!= DLT_EN10MB)
	{
		printf("pcap running in a NON-eth network.\n");
	}

	struct bpf_program filter;
	char filter_app[] = "ip";
	bpf_u_int32 net = 0;
	int ret32 = pcap_compile(handle, &filter, filter_app, 0, net);
	if(ret32 < 0)
	{
		printf("pcap_compile return %d, errbuf:%s\n", ret32, errbuf);
		return -1;
	}
	ret32 = pcap_setfilter(handle, &filter);
	if(ret32 < 0)
	{
		printf("pcap_setfilter return %d, errbuf:%s\n", ret32, errbuf);
		return -1;
	}

	const u_char *packet;
	struct pcap_pkthdr header;

	while (1)
	{
		packet = pcap_next(handle, &header);
		if(packet)
		{
			printf("LEN=%d:", header.len);
			for (unsigned int i=0;i<header.len;++i)
			{
				if ((i>=14 && i<32) || i+4 >= header.len)
					printf ("%02X",packet[i]);
				else if (i==32)
					printf ("...");
			}
			printf ("\n");
			//如果需要转发，则要打开另一个handle。
			//pcap_sendpacket(handle_dst,packet,header.len);
		}
	}
	pcap_close(handle);
	return 0;
}
